package cn.wolfcode.business.packageAudit.service.impl;

import java.io.InputStream;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import cn.wolfcode.business.bpmninfo.mapper.BusBpmnInfoMapper;
import cn.wolfcode.business.packageAudit.domain.vo.BusAuditHistory;
import cn.wolfcode.business.packageAudit.domain.vo.BusCarPackageAuditVO;
import cn.wolfcode.business.serviceItem.domain.BusServiceItem;
import cn.wolfcode.business.serviceItem.mapper.BusServiceItemMapper;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.packageAudit.mapper.BusCarPackageAuditMapper;
import cn.wolfcode.business.packageAudit.domain.BusCarPackageAudit;
import cn.wolfcode.business.packageAudit.service.IBusCarPackageAuditService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 套餐审核Service业务层处理
 * 
 * @author wolfcode
 * @date 2023-06-04
 */
@Service
@Transactional
public class BusCarPackageAuditServiceImpl implements IBusCarPackageAuditService 
{
    @Autowired
    private BusCarPackageAuditMapper busCarPackageAuditMapper;

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private BusServiceItemMapper serviceItemMapper;
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;

    /**
     * 查询套餐审核
     * 
     * @param id 套餐审核主键
     * @return 套餐审核
     */
    @Override
    public BusCarPackageAudit selectBusCarPackageAuditById(Long id)
    {
        return busCarPackageAuditMapper.selectBusCarPackageAuditById(id);
    }

    /**
     * 查询套餐审核列表
     * 
     * @param busCarPackageAudit 套餐审核
     * @return 套餐审核
     */
    @Override
    public List<BusCarPackageAudit> selectBusCarPackageAuditList(BusCarPackageAudit busCarPackageAudit)
    {
        return busCarPackageAuditMapper.selectBusCarPackageAuditList(busCarPackageAudit);
    }

    /**
     * 新增套餐审核
     * 
     * @param busCarPackageAudit 套餐审核
     * @return 结果
     */
    @Override
    public int insertBusCarPackageAudit(BusCarPackageAudit busCarPackageAudit)
    {
        busCarPackageAudit.setCreateTime(DateUtils.getNowDate());
        return busCarPackageAuditMapper.insertBusCarPackageAudit(busCarPackageAudit);
    }

    /**
     * 修改套餐审核
     * 
     * @param busCarPackageAudit 套餐审核
     * @return 结果
     */
    @Override
    public int updateBusCarPackageAudit(BusCarPackageAudit busCarPackageAudit)
    {
        return busCarPackageAuditMapper.updateBusCarPackageAudit(busCarPackageAudit);
    }

    /**
     * 批量删除套餐审核
     * 
     * @param ids 需要删除的套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteBusCarPackageAuditByIds(Long[] ids)
    {
        return busCarPackageAuditMapper.deleteBusCarPackageAuditByIds(ids);
    }

    /**
     * 删除套餐审核信息
     * 
     * @param id 套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteBusCarPackageAuditById(Long id)
    {
        Assert.notNull(id,"非法操作");
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper.selectBusCarPackageAuditById(id);
        Assert.notNull(busCarPackageAudit,"非法操作");
        Assert.state(busCarPackageAudit.getStatus() == 0,"必须是审核中状态才能撤销");
        runtimeService.deleteProcessInstance(busCarPackageAudit.getInstanceId(),null);

        serviceItemMapper.changeAuditStatus(busCarPackageAudit.getServiceItemId(), BusServiceItem.AUDITSTATUS_INIT);
        busCarPackageAudit.setStatus(BusCarPackageAudit.STATUS_CANCEL);
        return busCarPackageAuditMapper.updateBusCarPackageAudit(busCarPackageAudit);
    }

    @Override
    public InputStream getAuditProcess(Long id) {
        Assert.notNull(id,"非法操作");
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper.selectBusCarPackageAuditById(id);
        Assert.notNull(busCarPackageAudit,"非法操作");
        List<String> activeActivityIds = Collections.EMPTY_LIST;
        if(BusCarPackageAudit.STATUS_IN_ROGRESS.equals(busCarPackageAudit.getStatus())){
            Task task = taskService.createTaskQuery().processInstanceId(busCarPackageAudit.getInstanceId()).singleResult();
            if(task != null){
                activeActivityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
            }
//            activeActivityIds = runtimeService.getActiveActivityIds(busCarPackageAudit.getInstanceId());
        }

        //业务线
//        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.queryBpmnInfoByBpmnType(BusBpmnInfo.PACKAGE_AUDIT_TYPE);
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
//                .processDefinitionKey(busBpmnInfo.getProcessDefinitionKey())
//                .processDefinitionVersion(busBpmnInfo.getVersion().intValue())
//                .singleResult();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(busCarPackageAudit.getInstanceId()).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        InputStream inputStream = generator.generateDiagram(bpmnModel, activeActivityIds, Collections.EMPTY_LIST,
                "宋体", "宋体", "宋体");
        return inputStream;
    }

    @Override
    public void auditTask(BusCarPackageAuditVO busCarPackageAuditVO) {
        Assert.notNull(busCarPackageAuditVO,"非法操作");
        Assert.notNull(busCarPackageAuditVO.getId(),"非法操作");
        Assert.notNull(busCarPackageAuditVO.getAuditOpinion(),"非法操作");
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper
                .selectBusCarPackageAuditById(busCarPackageAuditVO.getId());
        Assert.notNull(busCarPackageAudit,"非法操作");
        Assert.state(BusCarPackageAudit.STATUS_IN_ROGRESS.equals(busCarPackageAudit.getStatus()),
                "要审核中状态才能审核");

        Map<String,Object> map = new HashMap<>();
        boolean flag = BusCarPackageAudit.AUDIT_OPINION_AGREE.equals(busCarPackageAuditVO.getAuditOpinion());
        map.put("shopOwner",flag);

        Task task = taskService.createTaskQuery()
                .processInstanceId(busCarPackageAudit.getInstanceId()).singleResult();
        taskService.addComment(task.getId(),busCarPackageAudit.getInstanceId(),
                "["+ SecurityUtils.getUsername() +"的审核意见是:]" + busCarPackageAuditVO.getAuditInfo() + "---" + flag);


        taskService.complete(task.getId(),map);

        if(flag){
            List<Task> list = taskService.createTaskQuery().processInstanceId(busCarPackageAudit.getInstanceId()).list();
            if(list.size() == 0){
                busCarPackageAudit.setStatus(BusCarPackageAudit.STATUS_PASS);
                busCarPackageAuditMapper.updateBusCarPackageAudit(busCarPackageAudit);
                serviceItemMapper.changeAuditStatus(busCarPackageAudit.getServiceItemId(), BusServiceItem.AUDITSTATUS_APPROVED);
            }
        } else {
            busCarPackageAudit.setStatus(BusCarPackageAudit.STATUS_REJECT);
            busCarPackageAuditMapper.updateBusCarPackageAudit(busCarPackageAudit);
            serviceItemMapper.changeAuditStatus(busCarPackageAudit.getServiceItemId(), BusServiceItem.AUDITSTATUS_REPLY);
        }
    }

    @Override
    public List<BusCarPackageAudit> selectMyBusCarPackageAuditList(BusCarPackageAudit busCarPackageAudit) {
        List<Task> list = taskService.createTaskQuery().taskAssignee(SecurityUtils.getUserId().toString()).list();
        if (list.size() == 0){
            return Collections.EMPTY_LIST;
        }
        List<String> ids = list.stream().map(task -> task.getProcessInstanceId()).collect(Collectors.toList());

        return busCarPackageAuditMapper.selectBusCarPackageAuditByIds(ids);
    }

    @Override
    public List<BusCarPackageAudit> selectmyDoneList(BusCarPackageAudit busCarPackageAudit) {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(SecurityUtils.getUserId().toString()).finished().list();
        if (list.size() == 0){
            return Collections.EMPTY_LIST;
        }
        List<String> ids = list.stream().map(historicTaskInstance -> historicTaskInstance.getProcessInstanceId()).collect(Collectors.toList());
        return busCarPackageAuditMapper.selectBusCarPackageAuditByIds(ids);
    }

    @Override
    public List<BusAuditHistory> getBusAuditHistoryByBusPackageAuditId(Long id) {
        Assert.notNull(id,"非法操作");
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper.selectBusCarPackageAuditById(id);
        Assert.notNull(busCarPackageAudit,"非法操作");
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(busCarPackageAudit.getInstanceId())
                .list();
        List<BusAuditHistory> list = new ArrayList<>();
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            BusAuditHistory busAuditHistory = new BusAuditHistory();
            busAuditHistory.setTaskName(historicTaskInstance.getName());
            busAuditHistory.setStartTime(historicTaskInstance.getStartTime());
            busAuditHistory.setEndTime(historicTaskInstance.getEndTime());
            if(historicTaskInstance.getDurationInMillis() != null){
                busAuditHistory.setAuditUseTime(DateUtils.getDatePoor(historicTaskInstance.getEndTime(),
                        historicTaskInstance.getStartTime()));
            }
            List<Comment> taskComments = taskService.getTaskComments(historicTaskInstance.getId());
            StringBuilder sb = new StringBuilder();
            for (Comment comment : taskComments) {
                sb.append(comment.getFullMessage());
            }
            busAuditHistory.setAuditInfo(sb.toString());
            list.add(busAuditHistory);
        }
        return list;
    }
}
